/**
 * @(#)Logger.java Mar 6, 2007
 *
 * Copyright (c) 2005-2010 Psiqueware S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information Psiqueware S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : AngelElectrico
 * <br/>Creaci&oacute;n: Mar 6, 2007 - 1:42:31 PM
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li>Mar 6, 2007 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.</li>
 *
 * </ul>
 */

package com.psiqueware.alheli.logging;

import com.psiqueware.alheli.basico.util.StringUtil;

/**
 * Bitacora para una clase dada.
 * <br/>Paquete Original: com.psiqueware.basico.logging
 * <br/>Nombre  Original: Logger
 * <br/>Oprima para ver : <a href="Logger.java.html"><i>C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.1 Mar 6, 2007 1:42:31 PM
 */
public interface Logger
{

    /**
     * Se utiliza para mensajes similares al modo "verbose" en otras aplicaciones.
     * Implica un alto detalle de logeo.
     *
     * @param o object a imprimir.
     */
    void info(Object o);

    /**
     * Se utiliza para mensajes similares al modo "verbose" en otras aplicaciones.
     * Implica un alto detalle de logeo.
     *
     * @param o         object a imprimir.
     * @param throwable a registrar en la bit&aacute;cora.
     */
    void info(Object o, Throwable throwable);

    /**
     * Se utiliza para escribir mensajes de depuraci&oacute;n.
     * Estos eventos este m_log no debe estar activado cuando la aplicaci&oacute;n se encuentre en producci&oacute;n.
     *
     * @param o object
     */
    void debug(Object o);

    /**
     * Se utiliza para escribir mensajes de depuraci&oacute;n.
     * Estos eventos este m_log no debe estar activado cuando la aplicaci&oacute;n se encuentre en producci&oacute;n.
     *
     * @param o         object
     * @param throwable a registrar en la bit&aacute;cora.
     */
    void debug(Object o, Throwable throwable);

    /**
     * Se utiliza para mensajes de alerta sobre eventos que se desea mantener constancia.
     * Estos eventos no afectan el correcto funcionamiento del programa.
     * A partir de este nivel se pretende utilizar en producci&oacute;n los logs.
     *
     * @param o object
     */
    void warn(Object o);

    /**
     * Se utiliza para mensajes de alerta sobre eventos que se desea mantener constancia.
     * Estos eventos no afectan el correcto funcionamiento del programa.
     * A partir de este nivel se pretende utilizar en producci&oacute;n los logs.
     *
     * @param o         object
     * @param throwable a registrar en la bit&aacute;cora.
     */
    void warn(Object o, Throwable throwable);

    /**
     * Se utiliza en mensajes de error de la aplicaci&oacute;n que se desea guardar.
     * Estos eventos afectan al programa pero lo dejan seguir funcionando, como por ejemplo que alg&uacute;n par&aacute;metro de configuraci&oacute;n no es correcto y se carga el par&aacute;metro por defecto.
     *
     * @param o object
     */
    void error(Object o);

    /**
     * Se utiliza en mensajes de error de la aplicaci&oacute;n que se desea guardar.
     * Estos eventos afectan al programa pero lo dejan seguir funcionando, como por ejemplo que alg&uacute;n par&aacute;metro de configuraci&oacute;n no es correcto y se carga el par&aacute;metro por defecto.
     *
     * @param o         object
     * @param throwable a registrar en la bit&aacute;cora.
     */
    void error(Object o, Throwable throwable);

    /**
     * Se utiliza para mensajes cr&iacute;ticos del sistema.
     * Generalmente luego de guardar el mensaje el programa abortar&aacute;.
     *
     * @param o objeto a registrar en la bit&aacute;cora.
     */
    void fatal(Object o);

    /**
     * Se utiliza para mensajes cr&iacute;ticos del sistema.
     * Generalmente luego de guardar el mensaje el programa abortar&aacute;.
     *
     * @param o         objeto a registrar en la bit&aacute;cora.
     * @param throwable a registrar en la bit&aacute;cora.
     */
    void fatal(Object o, Throwable throwable);

    boolean isDebugEnabled();

    boolean isInfoEnabled();

    class Formato
    {

        public static String formatea(Object o)
        {
            if (null == o)
            {
                return null;
            }
            else if (o instanceof Throwable)
            {
                return getStackTrace((Throwable) o);
            }
            else
            {
                return StringUtil.sustituyeEntidadesHTML(o.toString());
            }
        }

        private static final String PACKAGE_LOGGERS = Logger.class.getPackage().getName();

        /**
         * Facilita la vizualici&oacute;n de los mensajes de error en las bit&aacute;coras.
         *
         * @param t error mapeado.
         *
         * @return la cadena con la pila de trazos bien formateada y sin omitir trazos.
         *
         * @noinspection HardcodedLineSeparator, MethodWithMultipleLoops
         */
        private static String getStackTrace(final Throwable t)
        {

            final StringBuilder sb = new StringBuilder(t.getLocalizedMessage() == null ? t.getClass().getSimpleName() : (StringUtil.sustituyeEntidadesHTML(t.getLocalizedMessage())));
            sb.append("\n");
            StackTraceElement[] stackTraceElements = t.getStackTrace();
            for (StackTraceElement ste : stackTraceElements)
            {
                final String strStackTraceElement = ste.toString();
                if (strStackTraceElement.startsWith(PACKAGE_LOGGERS)) continue;
                sb.append("\tat ").append(StringUtil.sustituyeEntidadesHTML(strStackTraceElement)).append("\n");
            }

            if (t.getCause() != null)
            {
                sb.append("\nCausada por " + getStackTrace(t.getCause()));
            }
            return sb.toString();
        }
    }

}

